/**
 * Software License, Version 1.0
 *
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 *
 *
 *Redistribution and use in source and binary forms, with or without
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For
 * further information contact the Community Grids Lab at
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and
 * wherever such third-party acknowledgments normally appear.
 *
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering,
 * shall not be used to endorse or promote products derived from this software
 * without prior written permission from Indiana University.  For written
 * permission, please contact the Advanced Research and Technology Institute
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering,
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 *
 *
 * Indiana University provides no reassurances that the source code provided
 * does not infringe the patent or any other intellectual property rights of
 * any other entity.  Indiana University disclaims any liability to any
 * recipient for claims brought by any other entity based on infringement of
 * intellectual property rights or otherwise.
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS.
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS",
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION
 *GENERATED USING SOFTWARE.
 */

/**
 * <p>Title: DataAccessObject</p>
 * <p>Description: Creates an instance of DataAccessObject to
 * do task on database</p>
 * @author Xi Rao and Beytullah Yildiz
 * @author modified by Hasan BUlut
 * $Date$
 */

package cgl.narada.service.storage.db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import cgl.narada.service.ServiceException;

public class DataAccessObject {

    //  private String     moduleName         = "DataAccessObject: ";
    //  private String     jdbcDriver         = "org.postgresql.Driver";
    //  private String     connectionInfo     = "jdbc:postgresql://bozdag.ucs.indiana.edu:5432/NbPersistence";
    //  private String     connectionProvider = "jdbc:postgresql";
    //  private String     connectionHost     = "localhost";
    //  private String     connectionPort     = "5432";
    //  private String     connectionDatabase = "NbPersistence";
    //  private String     dbUserName         = "nbtest";
    //  private String     dbPassword         = "nbtest";

    private String moduleName = "rtsp:DataAccessObject: ";
    private String jdbcDriver = "org.gjt.mm.mysql.Driver";
    private String connectionInfo = "jdbc:mysql://localhost:3306/NbPersistence";
    private String connectionProvider = "jdbc:mysql";
    private String connectionHost = "localhost";
    private String connectionPort = "3306";
    private String connectionDatabase = "NbPersistence";
    private String dbUserName = "";
    private String dbPassword = "";

    private Connection connection;

    /**
     * default constructor
     * to initilize a connection required methods should be
     * called sequentially as follows
     * 1-) setDriver(parameter)
     * 2-) setConnnectionInfo(parameters)
     * 3-) setUserParameters(parameters) optional
     * 4-) initilizeConnection();
     */

    public DataAccessObject() throws ServiceException {
    }

    /**
     * sets database driver
     * @param driver
     */
    public void setDriver(String driver) {
        jdbcDriver = driver;
        System.out.println("using driver:" + driver);
    }

    /**
     * sets connection parameters
     * @param provider
     * @param host
     * @param db
     */
    public void setConnectionParameters(String provider, String host, String db) {
        connectionProvider = provider;
        connectionHost = host;
        connectionPort = "";
        connectionDatabase = db;

    }

    /**
     * sets connection parameters
     * @param provider
     * @param host
     * @param port
     * @param db
     */
    public void setConnectionParameters(String provider, String host,
                                        String port, String db) {
        connectionProvider = provider;
        connectionHost = host;
        connectionPort = port;
        connectionDatabase = db;

    }

    /**
     * sets connection info without setting parameters
     * @param cinfo connection information
     */
    public void setConnnectionInfo(String cinfo) {
        connectionInfo = cinfo;
    }

    /**
     * compose connection information from provided parameters
     * @param provider
     * @param host
     * @param db
     */
    public void setConnnectionInfo(String provider, String host, String db) {

        connectionInfo = provider + "://" + host + "/" + db;
        System.out.println("connection info:" + connectionInfo);
        setConnectionParameters(provider, host, db);

    }

    /**
     * compose connection information from provided parameters
     * @param provider
     * @param host
     * @param port
     * @param db
     */
    public void setConnnectionInfo(String provider, String host, String port,
                                   String db) {

        connectionInfo = provider + "://" + host + ":" + port + "/" + db;
        System.out.println("connection info:" + connectionInfo);
        setConnectionParameters(provider, host, port, db);
    }

    /**
     * @return connection information to connect database
     */
    public String getConnectionInfo() {
        return connectionInfo;
    }

    /**
     * sets user name and passwords
     * @param uname database user name
     * @param password database user password
     */
    public void setUserParameters(String uname, String password) {
        dbUserName = uname;
        dbPassword = password;

    }

    public Connection getConnection() {
        return connection;
    }

    /**
     * initialize the database connection
     * @throws ServiceException
     */
    public void initilizeConnection() throws ServiceException {
        System.out.println(moduleName + "Initializing connection !");
        loadJDBCDriver();
        boolean specifiedUserAndPassword = false;

        if (dbUserName != null && dbPassword != null) {
            if (dbUserName != "" && dbPassword != "") {
                specifiedUserAndPassword = true;
            }
        }

        try {

            if (specifiedUserAndPassword) {
                System.out.println(moduleName +
                                   "Trying to create a connection "
                                   + "UserId =" + dbUserName + " Password =" +
                                   dbPassword);
                connection = DriverManager.getConnection(connectionInfo,
                        dbUserName,
                        dbPassword);
            } else {
                System.out.println(moduleName
                                   +
                                   "UserId/Password for Database not specified");
                connection = DriverManager.getConnection(connectionInfo);
            }

            System.out.println(moduleName + "Database connection is succesful");
        } catch (SQLException ex) {
            throw new ServiceException(moduleName
                                       +
                                       "JDBC connection could not be initiated");
        }
    }

    /**
     * loads database driver
     * @throws ServiceException
     */
    private void loadJDBCDriver() throws ServiceException {

        try {
            Class.forName(jdbcDriver).newInstance();
        } catch (InstantiationException ex) {
            throw new ServiceException(moduleName
                                       + "JDBC driver instantiation exception");
        } catch (IllegalAccessException ex) {
            throw new ServiceException(moduleName
                                       + "JDBC driver illegal access exception");
        } catch (ClassNotFoundException ex) {
            throw new ServiceException(moduleName +
                                       "JDBC driver class not found");
        }

    }

    public java.sql.ResultSet executePreparedQuery(String pSqlQuery) throws
            ServiceException {
        try {
            if (connection == null) {
                System.out.println("\n\n\n" + moduleName
                                   + "Connection NOT initialized \n\n\n");
            }
            java.sql.PreparedStatement pStat = connection.prepareStatement(
                    pSqlQuery);
            long startTime = System.currentTimeMillis();
            java.sql.ResultSet resultSet = pStat.executeQuery();
            long endTime = System.currentTimeMillis();
            //added to fix memory leak
            //      pStat.close();
            return resultSet;
        } catch (SQLException se) {
            se.printStackTrace();
            throw new ServiceException(moduleName
                                       + "executePreparedQuery() exception [" +
                                       pSqlQuery + "] "
                                       + se.toString());
        }
    }

    public java.sql.PreparedStatement getPreparedStatement(String pSqlQuery) throws
            ServiceException {
        try {
            if (connection == null) {
                System.out.println("\n\n\n" + moduleName
                                   + "Connection NOT initialized \n\n\n");
            }
            java.sql.PreparedStatement pStat = connection.prepareStatement(
                    pSqlQuery);
            return pStat;
        } catch (SQLException se) {
            se.printStackTrace();
            throw new ServiceException(moduleName
                                       + "executePreparedQuery() exception [" +
                                       pSqlQuery + "] "
                                       + se.toString());
        }
    }

    /**
     * to insert, delete query to execute in DB
     * @param sqlQuery
     * @throws ServiceException
     */

    public int executeUpdate(String sqlQuery) throws ServiceException {
        try {
            java.sql.Statement stmt = connection.createStatement();
            int rowCount = stmt.executeUpdate(sqlQuery);
            //stmt.close();
            //added to fix memory leak
            stmt.close();
            return rowCount;
        } catch (SQLException se) {
            se.printStackTrace();
            throw new ServiceException(moduleName +
                                       " executeUpdate() exception ["
                                       + sqlQuery + "] " + se.toString());
        }
    }

    public static void main(String[] args) {
    }

}
